package org.execute.tool.adsPower;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * Adspower本地API通信客户端
 * 封装HTTP请求，处理API交互的通用逻辑（请求头、参数、响应解析）
 */
public class AdspowerClient implements AutoCloseable { // 实现AutoCloseable
    private final String baseUrl;
    private final String apiKey;
    private final CloseableHttpClient httpClient;
    private final ObjectMapper objectMapper;

    /**
     * 构造Adspower客户端
     * @param baseUrl API基础URL，默认通常是http://localhost:50325
     * @param apiKey 用于认证的API密钥
     * @throws IllegalArgumentException 当baseUrl或apiKey为null/空时抛出
     */
    public AdspowerClient(String baseUrl, String apiKey) {
        // 非空校验
        if (baseUrl == null || baseUrl.trim().isEmpty()) {
            throw new IllegalArgumentException("baseUrl不能为空");
        }
        if (apiKey == null || apiKey.trim().isEmpty()) {
            throw new IllegalArgumentException("apiKey不能为空");
        }
        // 处理baseUrl结尾斜杠，确保拼接正确
        this.baseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/";
        this.apiKey = apiKey;
        this.httpClient = HttpClients.createDefault();
        this.objectMapper = new ObjectMapper();
    }

    /**
     * 构造Adspower客户端，使用默认基础URL
     * @param apiKey 用于认证的API密钥
     */
    public AdspowerClient(String apiKey) {
        this("http://local.adspower.com:50325", apiKey);
    }
    /**
     * 发送GET请求
     * @param endpoint API端点（如"/api/v1/profile/list"）
     * @param params 请求参数（可为null）
     * @return API响应结果，以Map形式返回解析后的JSON数据
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> get(String endpoint, Map<String, String> params) throws IOException {
        // 构建完整URL
        StringBuilder urlBuilder = new StringBuilder(baseUrl)
                .append(stripLeadingSlash(endpoint)); // 处理endpoint前导斜杠

        // 添加查询参数（带URL编码）
        if (params != null && !params.isEmpty()) {
            urlBuilder.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String key = URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8.name());
                String value = URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.name());
                urlBuilder.append(key).append("=").append(value).append("&");
            }
            // 移除最后一个&
            urlBuilder.setLength(urlBuilder.length() - 1);
        }

        HttpGet httpGet = new HttpGet(urlBuilder.toString());
        return executeRequest(httpGet);
    }

    /**
     * 发送POST请求
     * @param endpoint API端点（如"/api/v1/profile/create"）
     * @param body 请求体（可为null）
     * @return API响应结果，以Map形式返回解析后的JSON数据
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> post(String endpoint, Map<String, Object> body) throws IOException {
        HttpPost httpPost = new HttpPost(baseUrl + stripLeadingSlash(endpoint));

        // 设置请求体，使用UTF-8编码
        if (body != null) {
            String jsonBody = objectMapper.writeValueAsString(body);
            StringEntity entity = new StringEntity(jsonBody, ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8));
            httpPost.setEntity(entity);
        }

        return executeRequest(httpPost);
    }

    /**
     * 执行HTTP请求并处理响应
     * @param request HTTP请求对象
     * @return 解析后的响应结果
     * @throws IOException 如果请求过程中发生错误
     */
    private Map<String, Object> executeRequest(HttpUriRequest request) throws IOException {
        // 设置通用请求头
        request.setHeader("Content-Type", "application/json;charset=UTF-8");
        request.setHeader("Authorization", "Bearer " + apiKey);
        request.setHeader("Accept", "application/json");

        try (CloseableHttpResponse response = httpClient.execute(request)) {
            HttpEntity entity = response.getEntity();
            String responseBody = entity != null ? EntityUtils.toString(entity, StandardCharsets.UTF_8) : "";

            // 检查响应状态
            int statusCode = response.getCode();
            if (statusCode < 200 || statusCode >= 300) {
                throw new IOException(String.format("API请求失败 [状态码: %d, 响应: %s]", statusCode, responseBody));
            }

            // 解析JSON响应（空响应返回空Map）
            return responseBody.isEmpty() ? new HashMap<>() : objectMapper.readValue(responseBody, Map.class);
        } catch (ParseException e) {
            // 将解析异常转为IOException，统一异常类型
            throw new IOException("响应解析失败: " + e.getMessage(), e);
        }
    }

    /**
     * 移除URL端点的前导斜杠，避免拼接时出现双斜杠
     */
    private String stripLeadingSlash(String endpoint) {
        return endpoint == null ? "" : endpoint.startsWith("/") ? endpoint.substring(1) : endpoint;
    }

    /**
     * 关闭HTTP客户端，释放资源（实现AutoCloseable）
     */
    @Override
    public void close() throws IOException {
        httpClient.close();
    }
}